package py.com.erpone.entity.almacen;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

import py.com.erpone.entity.dm.Almacen;
import py.com.erpone.entity.dm.Empleado;
import py.com.erpone.entity.dm.OrdenCompra;
import py.com.erpone.entity.dm.Proveedor;
import py.com.erpone.entity.dm.SolicitudPedidoDetalle;
@Entity
@NamedQueries(value={@NamedQuery(name="lote.all",query="select p from Lote p order by p.id"),
		@NamedQuery(name="lote.allItems",query="select d from LoteDetalle d where d.lote.id = :id order by d.id"),
		@NamedQuery(name="lote.allReceipt",query="select p from Lote p where p.situacion in ('R', 'F') order by p.id"),
		@NamedQuery(name="lote.allVerification",query="select p from Lote p where p.situacion in ('V', 'F') order by p.id"),
		@NamedQuery(name="lote.allLocation",query="select p from Lote p where p.situacion in ('F') order by p.id"),
		@NamedQuery(name="lote.importarAVerificacion",
		query="select p " +
			  "from Lote p " +
			  "where p.situacion = 'R'" +
			  "order by p.id"),
			  @NamedQuery(name="lote.importarAUbicacion",
				query="select p " +
					  "from Lote p " +
					  "where p.situacion = 'V'" +
					  "order by p.id")})
public class Lote implements Serializable{
	/**
	 *
	 */
	private static final long serialVersionUID = 1L;
	public static final String SITUACION_RECIBIDO = "R";
	public static final String SITUACION_DEVUELTO = "D";
	public static final String SITUACION_VERIFICADO = "V";
	public static final String SITUACION_FINALIZADO = "F";

	private static final HashMap<String, String> listSituacion = new HashMap<String, String>();

	static
	{
		listSituacion.put("Recibido", "R");
		listSituacion.put("Devuelto", "D");
		listSituacion.put("Verificado", "V");
		listSituacion.put("Finalizado", "F");
	}

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private long id;
	@NotNull
	private String situacion;
	@Transient
	private String situacionExtenso;
	@Column(columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
	private Date fecha;
	@ManyToOne
	private Empleado empleado;
	@ManyToOne
	private Almacen almacen;
	/***
	 * OBS:Si el modulo instalado es solamente el de almacen no tendra
	 * una ordenCompra por lo que ser� necesario una lista de productos
	 * y el proveedor asociado.
	 */
	
	@ManyToOne(fetch=FetchType.EAGER, cascade = CascadeType.ALL)
	private OrdenCompra ordenCompra;
	@ManyToOne
	private Proveedor proveedor;

	@OneToMany (fetch = FetchType.EAGER, mappedBy="lote",cascade = CascadeType.ALL)
	private List<LoteDetalle> loteDetalle;

	public Lote() {
		super();
	}


	public long getId() {
		return id;
	}


	public void setId(long id) {
		this.id = id;
	}


	public String getSituacion() {
		return situacion;
	}

	public void setSituacion(String situacion) {
		this.situacion = situacion;
	}

	@Transient
	public HashMap<String, String> getListSituacion() {
		return listSituacion;
	}

	
	public String getSituacionExtenso() {
		return situacionExtenso;
	}


	public void setSituacionExtenso(String situacionExtenso) {
		this.situacionExtenso = situacionExtenso;
	}


	public Date getFecha() {
		return fecha;
	}
	public void setFecha(Date fecha) {
		this.fecha = fecha;
	}
	public Empleado getEmpleado() {
		return empleado;
	}
	public void setEmpleado(Empleado empleado) {
		this.empleado = empleado;
	}
	public Almacen getAlmacen() {
		return almacen;
	}
	public void setAlmacen(Almacen almacen) {
		this.almacen = almacen;
	}
	public OrdenCompra getOrdenCompra() {
		return ordenCompra;
	}
	public void setOrdenCompra(OrdenCompra ordenCompra) {
		try {
			this.ordenCompra = ordenCompra;
			if(this.getOrdenCompra() != null && loteDetalle != null &&
					   this.getOrdenCompra().getSolicitudCotizacion() != null && 
					   this.getOrdenCompra().getSolicitudCotizacion().getSolicitudPedido() != null &&
					   this.getOrdenCompra().getSolicitudCotizacion().getSolicitudPedido().getSolicitudPedidosDetalle() != null){
						for (SolicitudPedidoDetalle item : this.getOrdenCompra().getSolicitudCotizacion().getSolicitudPedido().getSolicitudPedidosDetalle()) {
							LoteDetalle ld = new LoteDetalle();
							ld.setId(0l);
							ld.setCantidadSolicitada(item.getCantidad());
							ld.setCantidadRecibida(item.getCantidad());
							ld.setLote(this);				
							ld.setProducto(item.getProducto());
							loteDetalle.add(ld);
						}
						this.setProveedor(getOrdenCompra().getSolicitudCotizacion().getProveedor());
						
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	public Proveedor getProveedor() {
		return proveedor;
	}
	public void setProveedor(Proveedor proveedor) {
		this.proveedor = proveedor;
	}

	public List<LoteDetalle> getLoteDetalle() {
		return loteDetalle;
	}

	public void setLoteDetalle(List<LoteDetalle> loteDetalle) {
		this.loteDetalle = loteDetalle;
	}


	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((almacen == null) ? 0 : almacen.hashCode());
		result = prime * result
				+ ((empleado == null) ? 0 : empleado.hashCode());
		result = prime * result + ((fecha == null) ? 0 : fecha.hashCode());
		result = prime * result + (int) (id ^ (id >>> 32));
		result = prime * result
				+ ((loteDetalle == null) ? 0 : loteDetalle.hashCode());
		result = prime * result
				+ ((ordenCompra == null) ? 0 : ordenCompra.hashCode());
		result = prime * result
				+ ((proveedor == null) ? 0 : proveedor.hashCode());
		result = prime * result
				+ ((situacion == null) ? 0 : situacion.hashCode());
		return result;
	}


	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Lote other = (Lote) obj;
		if (almacen == null) {
			if (other.almacen != null)
				return false;
		} else if (!almacen.equals(other.almacen))
			return false;
		if (empleado == null) {
			if (other.empleado != null)
				return false;
		} else if (!empleado.equals(other.empleado))
			return false;
		if (fecha == null) {
			if (other.fecha != null)
				return false;
		} else if (!fecha.equals(other.fecha))
			return false;
		if (id != other.id)
			return false;
		if (loteDetalle == null) {
			if (other.loteDetalle != null)
				return false;
		} else if (!loteDetalle.equals(other.loteDetalle))
			return false;
		if (ordenCompra == null) {
			if (other.ordenCompra != null)
				return false;
		} else if (!ordenCompra.equals(other.ordenCompra))
			return false;
		if (proveedor == null) {
			if (other.proveedor != null)
				return false;
		} else if (!proveedor.equals(other.proveedor))
			return false;
		if (situacion == null) {
			if (other.situacion != null)
				return false;
		} else if (!situacion.equals(other.situacion))
			return false;
		return true;
	}


	@Override
	public String toString() {
		return "Lote [id=" + id + ", situacion=" + situacion + ", fecha="
				+ fecha + ", empleado=" + empleado + ", almacen=" + almacen
				+ ", ordenCompra=" + ordenCompra + ", proveedor=" + proveedor
				+ ", loteDetalle=" + loteDetalle + "]";
	}


}
